package com.ai.bitcoin.controller;

import com.ai.bitcoin.bean.CacheInfo;
import com.ai.bitcoin.constant.Bcc;
import com.ai.bitcoin.constant.Errors;
import com.ai.bitcoin.jpa.dao.CoinAnno2BccDao;
import com.ai.bitcoin.jpa.dao.CoinNews2BccDao;
import com.ai.bitcoin.jpa.entity.*;
import com.ai.bitcoin.jpa.service.BccBasicInfoService;
import com.ai.bitcoin.jpa.service.BccInfoEditService;
import com.ai.bitcoin.jpa.service.CoinPriceEstimateService;
import com.ai.bitcoin.redis.service.BccRedisService;
import com.ai.bitcoin.schedule.task.*;
import com.ai.bitcoin.service.WeixinCoinQrcodeService;
import com.ai.bitcoin.util.DateUtil;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@RequestMapping("/bitcoin")
@CrossOrigin
@Slf4j
@RestController
public class BitCoinController extends CommonController {
    @Value("${asyncTimeout}")
    long asyncTimeout;
    private RateLimiter rankLimiter;

    @Autowired
    private BccBasicInfoService bccBasicInfoService;
    @Autowired
    private BccRedisService bitCoinMetaCacheService;
    @Autowired
    private BccInfoEditService bccInfoEditService;
    @Autowired
    private RankTask rankTask;
    @Autowired
    private ReportTask reportTask;
    @Autowired
    private DetailBasicInfoTask detailBasicInfoTask;
    @Autowired
    private BccRedisService redisService;
    @Autowired
    private CurrentPriceTask currentPriceTask;
    @Autowired
    private DayPriceTask dayPriceTask;
    @Autowired
    private DailyInfoTask dailyInfoTask;
    @Autowired
    private IndexTask indexTask;
    @Autowired
    private WeixinCoinQrcodeService weixinCoinQrcodeService;
    @Autowired
    private CoinPriceEstimateService coinPriceEstimateService;
    @Autowired
    private CoinNews2BccDao coinNews2BccDao;
    @Autowired
    private CoinAnno2BccDao coinAnno2BccDao;

    @Value("${localCacheSecond}")
    int localCacheSecond;

    JSONArray bccIds;
    Date bccIdUpdateTime;
    Map<String, CacheInfo> homePage;


    @PostConstruct
    public void init() {
        int trafficSecond = 100;//db
        rankLimiter = RateLimiter.create(trafficSecond);
        homePage = new HashMap<>();
    }

    @ResponseBody
    @RequestMapping(value = "/hello", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> hello(final HttpServletRequest request,
                                        final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        return deferredContent(deferredResult, "hello");
    }

    @ResponseBody
    @RequestMapping(value = "/refreshBasicInfo", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> refreshBasicInfo(final HttpServletRequest request,
                                                   final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        detailBasicInfoTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/refreshDailyInfoTask", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> refreshDailyInfoTask(final HttpServletRequest request,
                                                       final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        dailyInfoTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/refreshPrice", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> refreshPrice(final HttpServletRequest request,
                                               final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        currentPriceTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/refreshDayPrice", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> refreshYesterday24Price(final HttpServletRequest request,
                                                          final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        dayPriceTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/search", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> search(final HttpServletRequest request,
                                         final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String word = reqJ.optString("word");
        if (StringUtils.isEmpty(word)) {
            return deferredContent(deferredResult, Errors.PARAMS_ERROR, Errors.PARAMS_ERROR_INFO);
        }
        if (bccIds == null || bccIds.size() == 0 || bccIdUpdateTime == null || (bccIdUpdateTime.getTime() - new Date().getTime()) > localCacheSecond * 1000) {
            String ids = redisService.getBccList();
            if (StringUtils.isNotEmpty(ids)) {
                bccIds = JSONArray.fromObject(ids);
                bccIdUpdateTime = new Date();
            }
        }
        String bccId = null;
        for (int i = 0; i < bccIds.size(); i++) {
            if (bccIds.getString(i).contains(word)) {
                bccId = bccIds.getString(i);
                break;
            }
        }
        if (StringUtils.isEmpty(bccId)) {
            return deferredContent(deferredResult, "no data");
        }
        else {
            String rank = redisService.getRank(Bcc.RankType.RANK_VALUE_TODAY_DETAIL, bccId);
            String h24Price = redisService.get24hPrice(bccId);
            String nowPrice = redisService.getCurrentPrice(bccId);
            String basicInfo = redisService.getBasicInfo(bccId);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("basicInfo", basicInfo);
            jsonObject.put("rank", rank);
            jsonObject.put("h24Price", h24Price);
            jsonObject.put("nowPrice", nowPrice);
            return deferredContent(deferredResult, jsonObject.toString());
        }

    }

    /**
     * 查询bitCoin rank
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/queryHomePageInfo", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryHomePageInfo(final HttpServletRequest request,
                                                    final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String rankType = reqJ.optString(Bcc.HttpRequest.RANK_TYPE);
        int pageSize = reqJ.optInt(Bcc.HttpRequest.PAGE_SIZE);
        int pageNum = reqJ.optInt(Bcc.HttpRequest.PAGE_NUM);

        String key = redisService.getRankKey(rankType, pageSize, pageNum);
        log.info("key:{}", key);
        CacheInfo cacheInfo = homePage.get(key);
        String content = getContent(cacheInfo);
        if (StringUtils.isEmpty(content)) {
            long start = System.currentTimeMillis();
            String rank = redisService.getRankPage(rankType, pageSize, pageNum);
            log.info("getRankPage consume:{}", (System.currentTimeMillis() - start));
            JSONArray showArray = new JSONArray();
            JSONArray jsonArray;
            if (StringUtils.isNotEmpty(rank)) {
                jsonArray = JSONArray.fromObject(rank);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject item = jsonArray.optJSONObject(i);
                    String bccId = item.optString("bccId");
                    String h24Price = redisService.get24hPrice(bccId);
                    if (!StringUtils.isEmpty(h24Price))
                        item.put("h24Price", JSONArray.fromObject(h24Price));
                    else
                        item.put("h24Price", "");
                    String nowPrice = redisService.getCurrentPrice(bccId);
                    item.put("nowPrice", nowPrice);
                    showArray.add(item);
                }
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", showArray);
            String bccCount = redisService.getBccCount(rankType);
            jsonObject.put("total", bccCount);
            homePage.put(key, new CacheInfo(jsonObject.toString()));
            content = jsonObject.toString();
        }
        return deferredContent(deferredResult, content);
    }

    /**
     * 获取今日推荐前5，根据涨的概率
     *
     * @return
     */
    @RequestMapping(value = "/findTodayRecommend", method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> findTodayRecommend(final HttpServletRequest request,
                                                     final HttpServletResponse response) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        String s = coinPriceEstimateService.findTodayRecommend(DateUtil.currentDate2Str("yyyyMMddHH"));
        return deferredContent(deferredResult, s);
    }


    @RequestMapping(value = "/queryTop", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryTop(final HttpServletRequest request,
                                           final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        String top = redisService.getTop();
        return deferredContent(deferredResult, top);
    }

    @RequestMapping(value = "/queryHomePageNum", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryHomePageNum(final HttpServletRequest request,
                                                   final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String rankType = reqJ.optString("rankType");
        String pageNum = redisService.getHomePageNum(rankType);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("pageNum", pageNum);
        return deferredContent(deferredResult, jsonObject.toString());
    }


    @RequestMapping(value = "/queryDetail", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryDetail(final HttpServletRequest request,
                                              final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString(Bcc.HttpRequest.BCCID);
        if (StringUtils.isEmpty(bccId)) {
            deferredContent(deferredResult, "no_bccId");
        }
        String rank = redisService.getRank(Bcc.RankType.RANK_VALUE_TODAY_DETAIL, bccId);
        String h24Price = redisService.get24hPrice(bccId);
        String dayPrice = redisService.getDayPrice(bccId);
        String nowPrice = redisService.getCurrentPrice(bccId);
        String todayPrice = redisService.getTodayPrice(bccId);
        String basicInfo = redisService.getBasicInfo(bccId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("basicInfo", basicInfo);
        jsonObject.put("rank", rank);
        jsonObject.put("dayPrice", dayPrice);
        jsonObject.put("todayPrice", todayPrice);
        jsonObject.put("h24Price", h24Price);
        jsonObject.put("nowPrice", nowPrice);
        return deferredContent(deferredResult, jsonObject);
    }

    @RequestMapping(value = "/queryCoinTrend", method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryCoinTrend(final HttpServletRequest request,
                                                 final HttpServletResponse response, @RequestParam String bccId) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        String trend = coinPriceEstimateService.queryCoinTrend(bccId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("trend", trend);
        return deferredContent(deferredResult, jsonObject);
    }

    @RequestMapping(value = "/queryDayPrice", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryDayPrice(final HttpServletRequest request,
                                                final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString(Bcc.HttpRequest.BCCID);
        if (StringUtils.isEmpty(bccId)) {
            deferredContent(deferredResult, "no_bccId");
        }
        String dayPrice = redisService.getDayPrice(bccId);
        if (StringUtils.isEmpty(dayPrice)) {
            return deferredContent(deferredResult, "no_data");
        }
        return deferredContent(deferredResult, dayPrice);
    }

    @RequestMapping(value = "/queryCurrentPrice", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> queryCurrentPrice(final HttpServletRequest request,
                                                    final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString(Bcc.HttpRequest.BCCID);
        if (StringUtils.isEmpty(bccId)) {
            deferredContent(deferredResult, "no_bccId");
        }
        String currentPrice = redisService.getCurrentPrice(bccId);
        if (StringUtils.isEmpty(currentPrice)) {
            return deferredContent(deferredResult, "no_data");
        }
        return deferredContent(deferredResult, currentPrice);
    }

    @RequestMapping(value = "/refreshIndexInfo", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> refreshIndexInfo(final HttpServletRequest request,
                                                   final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (!rankLimiter.tryAcquire()) {
            return deferredContent(deferredResult, Errors.REQ_BLOCK, Errors.REQ_BLOCK_INFO);
        }
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        indexTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @RequestMapping(value = "/testRedis", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> testRedis(final HttpServletRequest request,
                                            final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        bitCoinMetaCacheService.put("name", "chuxiujian");
        String value = bitCoinMetaCacheService.get("name");
        return deferredContent(deferredResult, value);
    }

    @RequestMapping(value = "/cache2Redis", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> cache2Redis(final HttpServletRequest request,
                                              final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        rankTask.cache2Redis();
        return deferredContent(deferredResult, "success");
    }


    @ResponseBody
    @RequestMapping(value = "/rankTask", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> rankTask(final HttpServletRequest request,
                                           final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        BccScoreRule bccScoreRule = null;
        rankTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/reportTask", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> reportTask(final HttpServletRequest request,
                                             final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        reportTask.execute();
        return deferredContent(deferredResult, "success");
    }

    @ResponseBody
    @RequestMapping(value = "/getReport", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> getReport(final HttpServletRequest request,
                                            final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);

        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString(Bcc.HttpRequest.BCCID);
        if (StringUtils.isEmpty(bccId)) {
            deferredContent(deferredResult, "no_bccId");
        }
        JSONObject jsonObject = redisService.getReport(bccId);
        return deferredContent(deferredResult, jsonObject);
    }

    @ResponseBody
    @RequestMapping(value = "/getNews", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> getNews(final HttpServletRequest request,
                                          final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);

        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String id = reqJ.optString("id");
        if (StringUtils.isEmpty(id)) {
            deferredContent(deferredResult, "no_id");
        }
        String news = redisService.getNews(id);
        return deferredContent(deferredResult, news);
    }

    @ResponseBody
    @RequestMapping(value = "/getNull", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> getNull(final HttpServletRequest request,
                                          final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString("bccId");
        List<BccBasicInfo> list = bccBasicInfoService.findByBccIdAndRecordState(bccId, Bcc.RecordState.PUBLISH);
        String edits = "";
        if (list.size() == 1) {
            edits = list.get(0).getEditField();
        }
        return deferredContent(deferredResult, edits);
    }

    @ResponseBody
    @RequestMapping(value = "/setValue", method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public DeferredResult<String> setValue(final HttpServletRequest request,
                                           final HttpServletResponse response, @RequestBody String json) {
        DeferredResult<String> deferredResult = new DeferredResult<>(asyncTimeout);
        if (StringUtils.isEmpty(json)) {
            return deferredContent(deferredResult, "BAD_REQUEST", "BAD_REQUEST");
        }
        JSONObject reqJ = JSONObject.fromObject(json);
        String bccId = reqJ.optString("bccId");
        reqJ.remove("bccId");
        Iterator iterator = reqJ.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
            String key = entry.getKey();
            String value = entry.getValue();
            List<BccInfoEdit> list = bccInfoEditService.findByBccIdAndFieldKey(bccId, key);
            BccInfoEdit bccInfoEdit;
            if (list.size() == 0) {
                bccInfoEdit = new BccInfoEdit();
                bccInfoEdit.setBccId(bccId);
                bccInfoEdit.setFieldKey(key);
                bccInfoEdit.setFieldValue(value);
                bccInfoEdit.setFieldState(Bcc.RecordState.PUBLISH);
                bccInfoEditService.save(bccInfoEdit);
            }
            else if (list.size() == 1) {
                bccInfoEdit = list.get(0);
                bccInfoEdit.setFieldValue(value);
                bccInfoEditService.save(bccInfoEdit);
            }
        }

        return deferredContent(deferredResult, "success");
    }

    @RequestMapping(value = "/qrcode", method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
    public String qrcode(final HttpServletRequest request) {
        weixinCoinQrcodeService.generateQrcode();
        return "success";
    }

    /**
     * 时间范围内新闻
     *
     * @param hours 时间小时
     * @return
     */
    @RequestMapping(value = "/news/{hours}", method = RequestMethod.GET)
    public DeferredResult<List<CoinNews2Bcc>> newsList(@PathVariable int hours) {
        DeferredResult<List<CoinNews2Bcc>> deferredResult = new DeferredResult<>(asyncTimeout);

        if (hours > 24 * 7 || hours <= 0) {
            deferredResult.setResult(Lists.newArrayList());
        }
        CompletableFuture.supplyAsync(() -> coinNews2BccDao.findByUpdateTimeIsBetween(DateUtils.addHours(new Date(), -hours), new Date())).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
        weixinCoinQrcodeService.generateQrcode();
        return deferredResult;
    }

    /**
     * 时间范围内公告
     *
     * @param hours 时间小时
     * @return
     */
    @RequestMapping(value = "/anno/{hours}", method = RequestMethod.GET)
    public DeferredResult<List<CoinAnno2Bcc>> annoList(@PathVariable int hours) {
        DeferredResult<List<CoinAnno2Bcc>> deferredResult = new DeferredResult<>(asyncTimeout);

        if (hours > 24 * 7 || hours <= 0) {
            deferredResult.setResult(Lists.newArrayList());
        }
        CompletableFuture.supplyAsync(() -> coinAnno2BccDao.findByUpdateTimeIsBetween(DateUtils.addHours(new Date(), -hours), new Date())).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
        weixinCoinQrcodeService.generateQrcode();
        return deferredResult;
    }

    public String getContent(CacheInfo cacheInfo) {
        if (cacheInfo == null) {
            return null;
        }
        Date time = cacheInfo.getTime();
        if (time == null) {
            return null;
        }
        long second = new Date().getTime() - time.getTime();
        if (second > localCacheSecond * 1000) {
            return null;

        }
        return cacheInfo.getContent();
    }


    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ResponseEntity<String> handleException(HttpServletRequest request,
                                                  HttpServletResponse response, RuntimeException e) {
        log.info("", e);
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("SERVICE_UNAVAILABLE");
    }
}